package com.comven.example.srouce.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.comven.example.srouce.constant.DataSourceType;
import com.comven.example.util.EncryptUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

@Configuration
public class DataSourceConfig {

    //加载配置数据信息
	/*@Bean(name = "LayoutData")
	public Map<String,Object> layoutData() {
	    YamlMapFactoryBean yaml = new YamlMapFactoryBean();
	    yaml.setResources(new ClassPathResource("data-sources-dev.yml"));
	    return yaml.getObject();
	}*/

    @Value("${data-sources.file}")
    private String datasourceFile;

    //加载配置数据信息
    @Bean(name = "LayoutData")
    public Map<String, Object> layoutData() {
        YamlMapFactoryBean yaml = new YamlMapFactoryBean();
        yaml.setResources(new ClassPathResource(datasourceFile)); //data-sources-dev.yml
        return yaml.getObject();
    }


    /**
     * 动态数据源添加 默认开启base数据源
     * 知识点：AbstractRoutingDataSource 进行逻辑转换调用数据源map
     */
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() throws Exception {
        Map<String, Object> base = getYamlMap(layoutData(), DataSourceType.base.name());
        Map<String, Object> local = getYamlMap(layoutData(), DataSourceType.local.name());
        Map<String, Object> file = getYamlMap(layoutData(), DataSourceType.file.name());
        DynamicDataSourceHodler dynamic = new DynamicDataSourceHodler();
        dynamic.setDefaultTargetDataSource(DruidDataSourceFactory.createDataSource(base));

        Map<Object, Object> dataSourceMap = new HashMap<Object, Object>();
        dataSourceMap.put(DataSourceType.base.name(), DruidDataSourceFactory.createDataSource(base));
        dataSourceMap.put(DataSourceType.local.name(), DruidDataSourceFactory.createDataSource(local));
        dataSourceMap.put(DataSourceType.file.name(), DruidDataSourceFactory.createDataSource(file));
        dynamic.setTargetDataSources(dataSourceMap);

        return dynamic;
    }

    /**
     * 对不同的数据源 dynamicDataSource() 进行切换事务
     */
    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        return new DataSourceTransactionManager(dynamicDataSource());
    }

    //解析嵌套map
    @SuppressWarnings("unchecked")
	/*private Map<String,Object> getYamlMap(Map<String,Object> input,String prefix){
		Map<String,Object> output = null;
		for (Entry<String, Object> entry : input.entrySet()) {
			if(prefix.equals(entry.getKey())) {
				output = (Map<String,Object>)entry.getValue();
				break;
			}
		}
		return output;
	}*/

    //解析嵌套map
    //@SuppressWarnings("unchecked")
    private Map<String, Object> getYamlMap(Map<String, Object> input, String prefix) {
        Map<String, Object> output = null;
        for (Entry<String, Object> entry : input.entrySet()) {
            if (prefix.equals(entry.getKey())) {
                output = (Map<String, Object>) entry.getValue();
                break;
            }
        }
        String str = null;
        if (output != null) {
            str = String.valueOf(output.get("password"));
            //如果加密此处解密
            if(str.contains("ENC")){
                String replaceStr = str.replace("ENC(", "");
                str = replaceStr.replace(")", "");
                str = EncryptUtil.smsDecryptByDes(str);
            }
        }
        output.put("password", str);
        return output;
    }
}
